#ifndef K_STREAM_ACTION_H
#define K_STREAM_ACTION_H
#pragma once

#include "KAutoPtr.h"
#include "KSocketAction.h"

class KPageList;
class KTaskTimer;
class KTicker;
class KTimerQueue;

class KStreamAction : public KSocketAction {
public:
    explicit KStreamAction(
        KPageList *poolRecv = NULL,
        KPageList *poolSend = NULL,
        KTimerQueue *queue = NULL);
    virtual ~KStreamAction();
public:
    size_t bytesToSend() const;
    bool isSending() const                  { return m_sending; }
    virtual size_t maxSendDelayMs() const   { return KDef::DefaultInterval; }
    virtual size_t maxSendKBps() const      { return 0; }
    virtual size_t maxSendSize() const      { return 0; }
    KPageList *recvPool() const;
    KPageList *sendPool() const;
protected:
    bool post()                             { return post(NULL, 0); }
    bool post(const void *data, size_t length, bool send = true);
protected:
    virtual void onClosing(bool stopped);
    virtual void onReceived(KKey *&key, void *data, size_t length, bool more);
    virtual void onSendComplete() {}
    virtual void onSent(KKey *&key, void *data, size_t length);
    virtual void onSocketChanged();
    virtual void process(KStorage *storage, bool ok);
private:
    void _timer();
    bool doSend();
    using KSocketAction::send;
    using KSocketAction::sendTo;
    using KSocketAction::transmit;
private:
    volatile bool           m_sending;
    KAutoPtr<KStorage>      m_recv;
    KAutoPtr<KStorage>      m_send;
    KAutoPtr<KTaskTimer>    m_timer;
    KAutoPtr<KTicker>       m_ticker;
    KDef::Life              m_life;
};

#endif // K_STREAM_ACTION_H